home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / smailsrc.zip / SMAIL.ZIP / UUX.C < prev    next >
Text File  |  1990-05-25  |  6KB  |  250 lines

  1. /*
  2.  *      uux.c: Very simple uux for smail
  3.  *
  4.  *      Stephen Trier
  5.  *      March 28, 1990
  6.  *
  7.  *      This uux is just barely smart enough to get the mail through.
  8.  *      It should work for rnews, but provisions will have to be added
  9.  *      to change the file owner from uucp to news.
  10.  *
  11.  *      This program is in the public domain.
  12.  *
  13.  *      Patch 1 written 5/23/90 by Stephen Trier: Change the definition
  14.  *          of localname to avoid short host name bug.  This way, both
  15.  *          uuio and uux will use the same filenames.
  16.  *
  17.  */
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include "config.h"
  23.  
  24. /* Array of filenames for easier code reading. */
  25. enum filetype {
  26.     CALL,
  27.     DATA,
  28.     XQT
  29.     };
  30.  
  31. enum nametype {
  32.     FAKE,               /* "Fake" names: what we call the file */
  33.     LOCAL,              /* "Local" names: what we _claim_ is the filename */
  34.     REMOTE              /* "Remote" names: the names given once sent */
  35.     };
  36.  
  37. char fn[3][3][80];    /* char filename [filetype][nametype][80] */
  38.  
  39. char *remotename;     /* Name of where we're calling */
  40. char cmd[128];       /* Command to execute there */
  41.  
  42. /*
  43.  *      ms_config: Load configuration information
  44.  */
  45.  
  46. char *ms_libdir = "\\usr\\lib",
  47.      *ms_spool = "\\usr\\spool\\uucp",
  48.      *localname = "invalid";
  49.  
  50. static struct table_entry table[] = {
  51.     "confdir", &ms_libdir,
  52.     "spooldir", &ms_spool,
  53.     "nodename", &localname,
  54.     NULL
  55.     } ;
  56.  
  57. /*
  58.  *      error: Print error message and terminate
  59.  */
  60.  
  61. void error(char *s)  /* Does not return! */
  62. {
  63.     fprintf(stderr, s);
  64.     perror("uux");
  65.     exit(1);
  66. }
  67.  
  68. /*
  69.  *      check_names: Check the remote system name against the systems file
  70.  */
  71.  
  72. void check_name(void)  /* Does not return if invalid name */
  73. {
  74.     FILE *fp;
  75.     char filename[80];
  76.     char name[80];
  77.  
  78.     sprintf(filename, "%s/systems", ms_libdir);
  79.     if ((fp = fopen(filename, "r")) == NULL)
  80.     error("uux: Can't open systems file.\n");
  81.     while (!feof(fp))  {
  82.     fscanf(fp, "%[^ \n\t]%*[^\n] ", name);
  83.     if (strcmp(name, remotename) == 0)  {
  84.         fclose(fp);
  85.         return;
  86.         }
  87.     }
  88.     fclose(fp);
  89.     fprintf(stderr, "uux: Can't connect to remote system %s\n", remotename);
  90.     exit(2);
  91. }
  92.  
  93. /*
  94.  *      find_params: Build the parameter list for the command
  95.  */
  96.  
  97. void find_params(char **argv)
  98. {
  99.     char *tmp;
  100.  
  101.     while (*argv != NULL)  {
  102.     for (tmp = *argv; ; )
  103.         if (*tmp == '\'')  {
  104.         *(strrchr(tmp, '\'')) = '\0';
  105.         tmp++;
  106.         }
  107.         else if (*tmp == '(')  {
  108.         *(strrchr(tmp, ')')) = '\0';
  109.         tmp++;
  110.         }
  111.         else
  112.         break;
  113.     strcat(cmd, " ");
  114.     strcat(cmd, tmp);
  115.     argv++;
  116.     }
  117. }
  118.  
  119. /*
  120.  *      make_filenames: Put together all of the filenames needed
  121.  */
  122.  
  123. int get_sequence(void)
  124. {
  125.     char filename[80];
  126.     FILE *fp;
  127.     int sequence = 0;
  128.  
  129.     sprintf(filename, "%s/seqf", ms_libdir);
  130.     if ((fp = fopen(filename, "r+")) == NULL)  {
  131.     if ((fp = fopen(filename, "w")) == NULL)
  132.         error("uux: Can't open sequence file\n");
  133.     }
  134.     else  {
  135.     fscanf(fp, "%d", &sequence);
  136.     rewind(fp);
  137.     sequence %= 1000;
  138.     }
  139.     fprintf(fp, "%3.3d", (sequence+1) % 1000);
  140.     fclose(fp);
  141.     return sequence;
  142. }
  143.  
  144. /* Templates for filenames.  P=path, C=character, S=system, N=seq. number */
  145. #define LOCALNAME(P,C,S,N)   "%s/%c_%s%04.4d.%03.3d",P,C,S,N,N
  146. #define REMOTENAME(C,S,N)  "%c.%.7s%04d",C,S,N
  147.  
  148. void make_filenames(void)
  149. {
  150.     int sequence;
  151.  
  152.     /* Get sequence number */
  153.     sequence = get_sequence();
  154.  
  155.     /* Make filenames */
  156.     sprintf(fn[CALL][FAKE], LOCALNAME(ms_spool, 'C', remotename, sequence));
  157.  
  158.     sprintf(fn[DATA][FAKE], LOCALNAME(ms_spool, 'D', remotename, sequence));
  159.     sprintf(fn[DATA][LOCAL], REMOTENAME('D', remotename, sequence));
  160.     sprintf(fn[DATA][REMOTE], REMOTENAME('D', localname, sequence));
  161.  
  162.     sprintf(fn[XQT][FAKE], LOCALNAME(ms_spool, 'D', localname, sequence));
  163.     sprintf(fn[XQT][LOCAL], REMOTENAME('D', localname, sequence));
  164.     sprintf(fn[XQT][REMOTE], REMOTENAME('X', localname, sequence));
  165. }
  166.  
  167. /*
  168.  *      make_data, make_call, make_xqt: Output the files
  169.  */
  170.  
  171. void make_data(void)
  172. {
  173.     FILE *fp;
  174.     char buf[80];
  175.  
  176.     if ((fp = fopen(fn[DATA][FAKE], "wb")) == NULL)
  177.     error("uux: Can't open data spool file\n");
  178.     while (fgets(buf, 80, stdin) != NULL)
  179.     fputs(buf, fp);
  180.     fclose(fp);
  181. }
  182.  
  183. void make_call(void)
  184. {
  185.     FILE *fp;
  186.  
  187.     if ((fp = fopen(fn[CALL][FAKE], "wb")) == NULL)
  188.     error("uux: Can't open call file\n");
  189.     fprintf(fp, "S %s %s uucp - %s 0666 uucp\n", fn[DATA][LOCAL],
  190.         fn[DATA][REMOTE], fn[DATA][REMOTE]);
  191.     fprintf(fp, "S %s %s uucp - %s 0666 uucp\n", fn[XQT][LOCAL],
  192.         fn[XQT][REMOTE], fn[XQT][REMOTE]);
  193.     fclose(fp);
  194. }
  195.  
  196. void make_xqt(void)
  197. {
  198.     FILE *fp;
  199.  
  200.     if ((fp = fopen(fn[XQT][FAKE], "wb")) == NULL)
  201.     error("uux: Can't open xqt control file\n");
  202.     fprintf(fp, "U uucp %s\n", localname);
  203.     fprintf(fp, "I %s\n", fn[DATA][REMOTE]);
  204.     fprintf(fp, "F %s\n", fn[DATA][REMOTE]);
  205.     fprintf(fp, "C %s\n", cmd);
  206.     fclose(fp);
  207. }
  208.  
  209. /*
  210.  *      main: Parse command line and set up
  211.  */
  212.  
  213. main(int argc, char *argv[])
  214. {
  215.     char *tmp;
  216.  
  217.     /* Read in the user configurations */
  218.     ms_config(table);
  219.  
  220.     /* Parse arguments */
  221.     argv++;
  222.     while ((*argv != NULL) && (**argv == '-'))
  223.     argv++;
  224.     if (*argv == NULL)
  225.     error("uux: Illegal command line\n");
  226.  
  227.     /* Get the name of the target system */
  228.     remotename = *argv;
  229.     if ((tmp = strchr(*argv, '!')) == NULL)
  230.     error("uux: Can't find remote system name\n");
  231.     *(tmp++) = '\0';
  232.     strcpy(cmd, tmp);
  233.  
  234.     /* Check that system's name for validity */
  235.     check_name();
  236.  
  237.     /* Figure out the command options */
  238.     find_params(++argv);
  239.  
  240.     /* Put together our filenames */
  241.     make_filenames();
  242.  
  243.     /* Output the files */
  244.     make_data();
  245.     make_call();
  246.     make_xqt();
  247.  
  248.     return 0;    /* All went well */
  249. }
  250.